import { refreshAuth } from '@/api/login'
import { setToken, removeToken } from '@/utils/auth'
import store from '@/store'

export let isRefreshing = false // 当前是否在请求刷新 Token
let requestQueue = [] // 将在请求刷新 Token 中的请求暂存起来，等刷新 Token 后再重新请求

// 执行暂存起来的请求
const executeQueue = error => {
  requestQueue.forEach(promise => {
    if (error) {
      promise.reject(error)
    } else {
      promise.resolve()
    }
  })

  requestQueue = []
}

const refreshToken = needLogin => {
  // 如果当前是在请求刷新 Token 中，则将期间的请求暂存起来
  if (isRefreshing) {
    return new Promise((resolve, reject) => {
      requestQueue.push({ resolve, reject })
    })
  }

  const loginPromise = () => {
    uni.showLoading({
      title: '登录中...'
    })
    return new Promise((resolve, reject) => {
      uni.login({
        provider: 'dingtalk',
        success: loginRes => {
          store
            .dispatch('permission/login', { code: loginRes.code, appid: process.env.VUE_APP_ID, keyid: process.env.VUE_APP_KEY_ID })
            .then(() => {
              uni.showToast({
                title: '登录成功',
                duration: 1500
              })
              uni.hideLoading()
              resolve()
            })
            .catch(err => {
              uni.hideLoading()
              reject(err)
            })
        }
      })
    })
  }

  const refreshPromise = () => {
    return new Promise((resolve, reject) => {
      refreshAuth()
        .then(res => resolve(res))
        .catch(err => reject(err))
    })
  }

  isRefreshing = true
  const refreshMethod = needLogin ? loginPromise : refreshPromise
  return new Promise(resolve => {
    refreshMethod()
      .then(res => {
        if (!needLogin) {
          const { token, expire } = res.data // expired_in
          setToken(token, expire)
        }
        isRefreshing = false
        resolve()
        executeQueue(null)
      })
      .catch(err => {
        removeToken()
        executeQueue(err)
      })
      .finally(() => {
        isRefreshing = false
      })
  })
}

export default refreshToken
